﻿/*****************************************************************************
* File			: src.Enemy
* Purpose		: Contains Declaration and Implementation for Enemy class
* Creation date : April 24, 2009
* Author		: Sami TOUIL
******************************************************************************/
package src 
{
	// Imports
	import flash.display.MovieClip
	import flash.utils.Timer
	import flash.events.*
	import flash.filters.*
	import flash.display.*
	import flash.geom.Point
	
	/**************************************
	* Class		: Enemy
	* Purpose	: Logic for enemies behavior
	* Parent	: MovieClip
	**************************************/
	public class Enemy extends MovieClip
	{
		// Class variables
		private 		var nXSpeed			:int;			// enemy horizontal speed
		private 		var nYSpeed			:int;			// enemy vertical speed
		
		private 		var nMinimumSpeed	:int 	=  2;	// Enemies minimum speed
		private 		var nMaximumSpeed	:int 	=  5;	// Enemies maximum speed
		private 		var nHMargin		:int 	= 30;	// higher margin for enemies pop position
		private 		var nLMargin		:int 	= 20;	// lower  margin for enemies pop position
		
		private	 		var shootTimer		:Timer;			// Timer used to manage Missile shooting
		
		public 			var myFilters		:Array;			// Array of bitmap filters that can be applied to the enemy
		
		public static 	var enemiesList		:Array	= [];	// Array storing all enemy instances
		
		public 			var nEnemyType		:int;			// Enemy type : define formula
		public static 	var nPointValue		:int	= 50;	// Point givent when destroying an enemy
		
		// Constructor
		public function Enemy()
		{
			// Set listener for ENTER_FRAME event
			addEventListener(Event.ENTER_FRAME, enterFrame);
			cacheAsBitmap = true;
			
			// Set the _x variable to 100px after the end of the background
			x = Game.WIDTH + 100;
			
			// Set the _y variable to a random position within [low margin, background height - high margin]
			y = nLMargin + Math.random() * (Game.HEIGHT - nHMargin - nLMargin);
			
			// Set the enemy speed (random between minimum and maximum speed)
			nXSpeed = Math.random()*(nMaximumSpeed - nMinimumSpeed) + nMinimumSpeed;
			nYSpeed = Math.random()*(nMaximumSpeed - nMinimumSpeed) + nMinimumSpeed;

			// Add enemy to instance list
			enemiesList.push(this);
			
			// Pick Random enemy type from 1 to 3, then set formula
			nEnemyType = Math.floor(Math.random()*3+1);
			textField.text = getEnemyFormula();
			
			// Add Enemy sprite
			Game.main.spriteClip.addChild(this);
			
			// add a dropshadow filter 
			var filter:BitmapFilter = new DropShadowFilter(3,45,0x000000,50,5,5);
           	filters = [filter];
			
			//start firing missiles
			initShootingInterval();
		}
		
		/***********************************************************
		* Method		: enterFrame
		* Purpose		: frame loop
		* Parameters	: e:Event
		* return		: void
		***********************************************************/
		public function enterFrame(e:Event)
		{
			// if the ship is not deleted
			if(Game.main.ship != null)
			{
				// Horizontal Enemy movement
				x -= nXSpeed;
				
				// Vertical movemetn management
				y += nYSpeed
				if(nYSpeed > 0 && y > Game.HEIGHT - nLMargin)
					nYSpeed *= -1;
				else if(nYSpeed < 0 && y < nHMargin)
					nYSpeed *= -1;
				
				
				// Manage collision with ship
				if(this.hitTestObject(Game.main.ship))
				{
					// Shake ship
					Game.main.ship.initShake();
					
					// Delete enemy instance
					takeDamage();
					
					// remove HP from ship
					Game.main.ship.updateHealth(-20);
					return;
				}
				// Collision management with Modules
				if(Game.main.ship.module1 != null && this.hitTestObject(Game.main.ship.module1))
				{				
					// Delete enemy instance
					takeDamage();
					
					// Remove health from ship
					Game.main.ship.module1.updateHealth(-50);
					return;
				}
				if(Game.main.ship.module2 != null && this.hitTestObject(Game.main.ship.module2))
				{				
					// Delete enemy instance
					takeDamage();
					
					// Remove health from ship
					Game.main.ship.module2.updateHealth(-50);
					return;
				}
				
				// Clear enemy instance once it's not in the frame anymore
				if(x < -100)
					onDelete();
			}
		}
		
		/***********************************************************
		* Method		: getEnemyFormula
		* Purpose		: Return a mathematical formula based on enemy type
		* Parameters	: None
		* return		: String : the formula
		***********************************************************/
		function getEnemyFormula():String
		{
			switch(nEnemyType)
			{
				case 1:
				return "x²+y²=z²";  // Pythagore
				case 2:
				return "e = mc ²";	// Restrained relativity
				case 3:
				return "A = πR ²";	// indentity
				default:
				return "<Unknown>";
			}
		}
		
		/***********************************************************
		* Method		: takeDamage
		* Purpose		: Remove health from the enemy instantly destroying it
		* Parameters	: None
		* return		: void
		***********************************************************/
		function takeDamage()
		{
			// Create and display reward point
			var d = new RewardPoint(x, y - 5, String(Enemy.nPointValue), 0xCC6600);
			Game.main.spriteClip.addChild(d);
			
			// update score
			Game.main.updateScore(Enemy.nPointValue);			
						
			// Delete
			onDelete();
		}
		
		/***********************************************************
		* Method		: initShootingInterval
		* Purpose		: Initialize shooting timer
		* Parameters	: None
		* return		: void
		***********************************************************/
		public function initShootingInterval()
		{
			var interval:int = 1;	// Shoot every second
			
			//create a timer instance to control it
			shootTimer = new Timer(interval * 1000, 0);
			shootTimer.addEventListener("timer", shoot);
			shootTimer.start();	
		}
				
		/***********************************************************
		* Method		: shoot
		* Purpose		: Manage the missile launch and position
		* Parameters	: e:TimerEvent
		* return		: void
		***********************************************************/
		function shoot(e:TimerEvent):void
		{
			// Create missile instance
			new EnemyMissile(x - 50, y, 0, 6 + ( Math.random() * 2 ) ,0);
		}
		
		/***********************************************************
		* Method		: onDelete
		* Purpose		: called for deleting the object instance
		* Parameters	: None
		* return		: void
		***********************************************************/
		public function onDelete()
		{
			// stop shooting timer
			shootTimer.stop();
			shootTimer.removeEventListener("timer", shoot);
			
			//add an explosion
			new Explosion(x, y);

			removeEventListener(Event.ENTER_FRAME, enterFrame);
			
			// Remove enemy instance from list
			for(var i:int = 0; i < enemiesList.length; i++)
			{
				if(enemiesList[i] == this)
				{
					enemiesList.splice(i,1);
					break;
				}
			}
		
			Game.main.spriteClip.removeChild(this);
		}
		
		/***********************************************************
		* Method		: onDeleteAll
		* Purpose		: called for deleting all Enemy instances
		* Parameters	: None
		* return		: void
		***********************************************************/
		static public function onDeleteAll()
		{
			while(Enemy.enemiesList.length > 0)
			{
				Enemy.enemiesList[0].onDelete();					
			}	
		}
		
		/***********************************************************
		* Method		: onTakeDamageAll
		* Purpose		: called for damaging all Enemy instances
		* Parameters	: None
		* return		: void
		***********************************************************/
		static public function onTakeDamageAll()
		{
			for (var i:int = Enemy.enemiesList.length-1; i>=0; i--)
			{
				Enemy.enemiesList[i].takeDamage();					
			}
		}		
	}
}